package socket;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * 聊天室客户端
 */
public class Client {
    /*
        java.net.Socket 套接字
        Socket封装了TCP协议的通讯细节，使用它可以与远端计算机建立连接，并基于一个
        输入与一个输出流的读写完成与远端计算机的交互。
     */
    private Socket socket;

    /**
     * 构造方法，用来初始化客户端
     */
    public Client(){
        try {
            /*
                Socket的实例化需要传入两个参数:
                参数1:服务端IP地址。其中"localhost"表示本机
                参数2:服务端开启的端口。这是一个整数1-65535之间
                我们通过IP地址找到网络上服务端所在的计算机，通过端口找到该机器上
                运行的服务端应用程序。
             */
            System.out.println("正在连接服务端...");
            socket = new Socket("176.6.13.185",8088);
            System.out.println("与服务端建立了连接!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 客户端开始工作的方法
     */
    public void start(){
        try {
            //启动用于读取服务端发送过来消息的线程
            ServerHandler handler = new ServerHandler();
            Thread t = new Thread(handler);
            t.start();

            /*
                Socket提供的方法:
                OutputStream getOutputStream()
                获取一个字节输出流，通过这个流写出的字节都会发送给远端计算机。
             */
            OutputStream out = socket.getOutputStream();
            //转换流(高级流),负责衔接字符与字节流，将写出的字符转换为字节
            OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
            //缓冲流(高级流),负责块写文本数据加速
            BufferedWriter bw = new BufferedWriter(osw);
            //PW(高级流)按行写出字符串，自动行刷新
            PrintWriter pw = new PrintWriter(bw,true);


            Scanner scanner = new Scanner(System.in);
            while(true){
                String line = scanner.nextLine();
                if("exit".equals(line)){
                    break;
                }
                pw.println(line);


            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Client client = new Client();
        client.start();
    }

    /**
     * 该线程负责循环读取服务端发送过来的消息
     */
    private class ServerHandler implements Runnable{
        public void run(){
            try {
                //通过socket获取输入流读取服务端发送过来的消息
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(
                                socket.getInputStream()
                        )
                );
                String message;
                while((message = br.readLine())!=null){
                    System.out.println(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}
